/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2014 abel533@gmail.com
 *
 * Permission is hereby granted， free of charge， to any person obtaining a copy
 * of this software and associated documentation files (the "Software")， to deal
 * in the Software without restriction， including without limitation the rights
 * to use， copy， modify， merge， publish， distribute， sublicense， and/or sell
 * copies of the Software， and to permit persons to whom the Software is
 * furnished to do so， subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS"， WITHOUT WARRANTY OF ANY KIND， EXPRESS OR
 * IMPLIED， INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY，
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM， DAMAGES OR OTHER
 * LIABILITY， WHETHER IN AN ACTION OF CONTRACT， TORT OR OTHERWISE， ARISING FROM，
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

package com.yifushidai.service.impl;

import com.yifushidai.service.IService;
import org.springframework.beans.factory.annotation.Autowired;
import tk.mybatis.mapper.common.Mapper;
import tk.mybatis.mapper.entity.Example;

import java.util.List;

/**
 * 通用Service
 *
 * @param <T>
 */
public abstract class BaseService<T> implements IService<T> {

    @Autowired
    protected Mapper<T> mapper;

    @Override
    public List<T> selectAll() {
        //说明：查询全部
        return mapper.selectAll();
    }

    @Override
    public List<T> select(T record) {
        //说明：根据实体类不为null的字段进行查询，条件全部使用=号and条件
        return mapper.select(record);
    }

    @Override
    public int selectCount(T record) {
        //说明：根据实体类不为null的字段查询总数，条件全部使用=号and条件
        return mapper.selectCount(record);
    }

    @Override
    public List<T> selectByExample(Example example) {
        //说明：根据Example条件进行查询
        //重点：这个查询支持通过Example类指定查询列，通过selectProperties方法指定查询列
        return mapper.selectByExample(example);
    }

    @Override
    public int selectCountByExample(Example example) {
        //说明：根据Example条件查询总数
        //重点：这个查询支持通过Example类指定查询列，通过selectProperties方法指定查询列
        return mapper.selectCountByExample(example);
    }

    @Override
    public T selectByKey(Object key) {
        //说明：根据主键字段进行查询，方法参数必须包含完整的主键属性，查询条件使用等号
        //重点：根据主键进行查询，必须保证结果唯一；单个字段做主键时，可以直接写主键的值；联合主键时，key可以是实体类，也可以是Map
        return mapper.selectByPrimaryKey(key);
    }

    @Override
    public int save(T record) {
        //说明：支持Oracle序列，UUID，类似Mysql的INDENTITY自动增长(自动回写) 优先使用传入的参数值，参数值空时，才会使用序列、UUID，自动增长
        //重点：插入一条数据，null的属性也会保存，不会使用数据库默认值
        return mapper.insert(record);
    }

    @Override
    public int saveNotNull(T record) {
        //说明：支持Oracle序列，UUID，类似Mysql的INDENTITY自动增长(自动回写) 优先使用传入的参数值，参数值空时，才会使用序列、UUID，自动增长
        //重点：插入一条数据，只插入不为null的字段，不会影响有默认值的字段
        return mapper.insertSelective(record);
    }

    @Override
    public int delete(T record) {
        //说明：根据实体类中字段不为null的条件进行删除，条件全部使用=号and条件
        return mapper.delete(record);
    }

    @Override
    public int deleteByKey(Object key) {
        //说明：根据主键字段进行删除，方法参数必须包含完整的主键属性
        //重点：通过主键进行删除，这里最多只会删除一条数据；单个字段做主键时，可以直接写主键的值；联合主键时，key可以是实体类，也可以是Map
        return mapper.deleteByPrimaryKey(key);
    }

    @Override
    public int deleteByExample(Example example) {
        //说明：根据Example条件进行删除，方法参数必须包含完整的主键属性
        //重点：通过Example条件进行删除，可删除多条数据
        return mapper.deleteByExample(example);
    }

    @Override
    public int updateAll(T record) {
        //说明：根据主键更新实体全部字段，null值会被更新
        //重点：根据主键进行更新，这里最多只会更新一条数据；参数为实体类
        return mapper.updateByPrimaryKey(record);
    }

    @Override
    public int updateNotNull(T record) {
        //说明：根据主键更新属性不为null的值
        //重点：根据主键进行更新；只会更新不是null的数据
        return mapper.updateByPrimaryKeySelective(record);
    }

    @Override
    public int updateByExampleSelective(T record, Example example) {
        //说明：根据Example条件更新属性不为null的值
        //重点：根据Example条件进行更新；只会更新不是null的数据
        return mapper.updateByExampleSelective(record, example);
    }

    public Mapper<T> getMapper() {
        return mapper;
    }
}